package com.yc.controller;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fasterxml.classmate.Annotations;
import com.yc.common.utils.AlyExcelUtil;
import com.yc.common.utils.Encrypt;
import com.yc.entity.User;
import com.yc.mapper.ClassInfoMapper;
import com.yc.service.impl.UserInfoServiceImpl;
import com.yc.vo.Result;
import com.yc.exception.CustomException;
import com.yc.mapper.UserMapper;
import com.yc.service.UserService;
import io.swagger.annotations.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.ui.Model;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.*;
import java.util.stream.Collectors;

@Api(tags = "教师管理控制器")
@RestController
@RequestMapping("/api/user")
public class UserController {

    @Resource
    private UserService userService;

    @Resource
    private UserMapper userMapper;
    @Resource
    private HttpServletRequest request;

    @Resource
    private UserInfoServiceImpl userInfoService;



    public User getUser() {
        User user = (User) request.getSession().getAttribute("user");
        if (user == null) {
            throw new CustomException("-1", "请登录");
        }
        return user;
    }


    @ApiOperation("修改用户信息")
    @PostMapping("/updateinfo")
    public void updateInfo(
            @RequestParam String username,
            @RequestParam String nickname,
            @RequestParam String phone
    ){
        userMapper.updateInfo(username,nickname,phone);
    }


    @GetMapping("/session")
    public Result<User> session() {
        return Result.success(getUser());
    }


    @ApiOperation("查询用户所在部门")
    @GetMapping("/selectDeptNameByTid/{tid}")
    public Result selectDeptNameByUdid(@PathVariable Long tid) {
        Result<List<String>> result = Result.success(userService.selectDeptNameByUdid(tid));
        return result;
    }


    @ApiOperation("新增用户")
    @PostMapping("/save")
    public Result<?> save(@RequestBody User user) {
        if (user.getPassword() == null) {
            user.setPassword(Encrypt.md5AndSha(user.getUsername()));
        }
        return Result.success(userService.save(user));
    }


    @ApiOperation("修改用户信息")
    @PostMapping("/dUpdate")
    public Result<?> update(@RequestBody User user) {
        return Result.success(userService.updateById(user));
    }


    @ApiOperation("修改密码")
    @PostMapping("/updatePassword")
    public Object updateps(User user) {
        return userService.updateByName(user);
    }


    @ApiOperation("比对密码")
    @PostMapping("/compare")
    public Object compare(User user) {
            return userService.compare(user);
    }


    @ApiOperation("删除用户")
    @GetMapping("/del/{id}")
    public Result<?> delete(@PathVariable Long id) {
        userService.removeById(id);
        return Result.success();
    }


    @ApiOperation("查询用户")
    @GetMapping("/{id}")
    public Result<User> findById(@PathVariable Long id) {
        return Result.success(userService.getById(id));
    }


    @ApiOperation("查询登录用户的权限")
    @GetMapping("/detail/{username}")
    public Result<User> findByUsername(@PathVariable String username) {
        return Result.success(userService.getbyUsername(username));
    }




    @ApiOperation("查询所有的系统用户（除了admin）")
    @GetMapping
    public Result<List<User>> findAll() {
        return Result.success(userService.list( Wrappers.<User>lambdaQuery().ne(User::getUsername, "admin").ne(User::getUsername,"wphcj")));
    }

    /**
    *@Description 查询所有辅导员
    *@Return
    *@Author dm
    *@Date Created in 2023/7/18 11:24
    **/
    @ApiOperation("查询所有的系统用户（除了admin）")
    @GetMapping("/getCounselor")
    public Result findCounselor() {
        LambdaQueryWrapper wrapper = Wrappers.<User>lambdaQuery()
                .ne(User::getUsername,"admin").ne(User::getUsername,"wphcj");
        List<User> users = userMapper.selectList(wrapper);
        users = users.stream().filter(user -> user.getRole().contains(2)).collect(Collectors.toList());
        return Result.success(users);
    }


    @ApiOperation("系统用户信息分页展示")
    @GetMapping("/page")
    public Result<IPage<User>> findPage(@RequestParam(required = false, defaultValue = "") String name,
                                        @RequestParam(required = false, defaultValue = "") String role,
                                        @RequestParam(required = false, defaultValue = "1") Integer pageNum,
                                        @RequestParam(required = false, defaultValue = "10") Integer pageSize) {
        // 筛选条件
        String username = null;
        String nickname = null;
        String newRole = null;
        if (org.apache.commons.lang3.StringUtils.isNumeric(name)){
            username = name;
        }else {
            nickname = name;
        }
        if (!role.equals("") && !role.equals("undefined")){
            newRole = role;
        }
        Page<User> page = new Page<>(pageNum, pageSize);
        Page<User> userPage = userService.selectAllUser(page, username, nickname, newRole);
        return Result.success(userPage);
    }


    @GetMapping("/export")
    public void export(HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = CollUtil.newArrayList();

        List<User> all = userService.list();
        for (User user : all) {
            Map<String, Object> row1 = new LinkedHashMap<>();
            row1.put("名称", user.getUsername());
            row1.put("手机", user.getPhone());
            list.add(row1);
        }

        // 2. 写excel
        ExcelWriter writer = ExcelUtil.getWriter(true);
        writer.write(list, true);

        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
        String fileName = URLEncoder.encode("用户信息", "UTF-8");
        response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ".xls");

        ServletOutputStream out = response.getOutputStream();
        writer.flush(out, true);
        writer.close();
        IoUtil.close(System.out);
    }



    /*@ApiOperation("解析excel后批量插入")
    @PostMapping("file/upload")
    public Result< List<User>> ExcelParse(@RequestParam("file") MultipartFile file, Model model) {
        try{
            String name=file.getOriginalFilename();
            if(!name.substring(name.length()-4).equals(".xls")){
                model.addAttribute("error","文件解析错误");
            }
            List<Map<String, Object>> list = AlyExcelUtil.excelToShopIdList(file.getInputStream()).get(0);
            User user ;
            List<User> userList = new ArrayList<>();
            for (int i = 0, l = list.size(); i < l; i++) {
                if(list.get(i).get("0") ==null || "".equals(list.get(i).get("0"))){
                    continue;
                }
                user = new User();
                user.setUsername((String) list.get(i).get("0"));
                user.setPassword(Encrypt.md5AndSha((String) list.get(i).get("0")));
                user.setNickname((String) list.get(i).get("1"));
                if(!StringUtils.isEmpty(String.valueOf(list.get(i).get("2"))) && !"".equals(String.valueOf(list.get(i).get("2")))){
                    user.setPhone((String) list.get(i).get("2"));
                }else{
                    user.setPhone("");
                }
                userList.add(user);

            }
            //自定义批量插入的mapper
            userMapper.batchInsert(userList);
            model.addAttribute("msg",list);
            return Result.success( userList);
        }catch (Exception e){
            e.printStackTrace();
            return Result.error(-1,"系统错误");
        }
    }*/

    @ApiOperation("文件上传学生信息")
    @PostMapping("/file/upload")
    public Result uploadStudent(@RequestParam("file") MultipartFile multipartFile, String uid) throws IOException {
        InputStream inputStream = multipartFile.getInputStream();
        int result = userService.upload(inputStream, uid);
        if (result == 0){
            return Result.success("文件上传成功!");
        }else {
            return Result.error("文件上传失败，在" + result + "行,请检查是否正确输入,只能包含中文、英文、数字");
        }
    }

    @ApiOperation("下载模板文件")
    @GetMapping("/downLoadTemplate")
    public Result<?> downLoadTemplate(HttpServletResponse response){
        Result result;
        try {
            userService.downloadTemplate(response);
            result = Result.success();
        } catch (IOException e) {
            e.printStackTrace();
            result = Result.error(e.getMessage());
        }
        return result;
    }

    @ApiOperation("获取服务器时间")
    @GetMapping("/get/time")
    public Result<?> getServerTime(){
        return Result.success(new Date());
    }


    @ApiOperation("重置密码")
    @PostMapping("/resettingPwd")
    public Result<?> resettingPwd(User user){
        if(org.apache.commons.lang3.StringUtils.isEmpty(user.getUsername()) || org.apache.commons.lang3.StringUtils.isBlank(user.getUsername())){
            return Result.error("修改失败,请稍后再试!");
        }
        int result = userService.resettingPwd(user);
        if(result>0){
            return Result.success();
        }else{
            return Result.error("修改失败,请稍后再试!");
        }
    }
    @ApiOperation("检查当前用户是否是初始密码")
    @GetMapping("/checkPassword")
    public Result checkPassword(HttpServletRequest request){
        return Result.success(userService.checkPassword(request));
    }
    /**
     * 查询所有的上课老师
     * @return
     */
    @ApiOperation("查询所有上课老师的信息")
    @GetMapping("/getTeachers")
    public Result queryTeacher(){
        List<User> users = userService.queryTeacher();
        if(users == null){
            return Result.error("初始化失败，请刷新");
        }else {
            return Result.success(users);
        }
    }
    @ApiOperation("根据专业班级一学年的课程数")
    @GetMapping("/queryTeaData")
    public Result queryTeaData(String school_year,String cname){
        List<Map<String, Object>> maps = userInfoService.queryUserClassTotalByschoolYear(school_year, cname);
        return Result.success(maps);
    }
    @ApiOperation("根据专业班级上学期的课程数")
    @GetMapping("/queryTeaDataUp")
    public Result queryTeaDataUp(String school_year,String cname){
        List<Map<String, Object>> maps = userInfoService.queryUserClassTotalByschoolYearUp(school_year, cname);
        return Result.success(maps);
    }

    @ApiOperation("根据专业下学期的课程数")
    @GetMapping("/queryTeaDataDown")
    public Result queryTeaDataDown(String school_year,String cname){
        List<Map<String, Object>> maps = userInfoService.queryUserClassTotalByschoolYearDown(school_year, cname);
        return Result.success(maps);
    }

    @ApiOperation("直接查出教师一年的课程数")
    @RequestMapping("/selectByteaYear")
    public Result selectByteaYear( @RequestParam("school_year") String school_year,@RequestParam("mname") String mname,@RequestParam("yearnumber") String yearnumber,@RequestParam("cname") String cname){
        List<Map<String, Object>> maps = userService.selectByteaYear(school_year,mname,yearnumber,cname);
        return Result.success(maps);
    }
    @ApiOperation("直接查出教师上半年的课程数")
    @RequestMapping("/selectByteaUpYear")
    public Result selectByteaUpYear( @RequestParam("school_year") String school_year,@RequestParam("mname") String mname,@RequestParam("yearnumber") String yearnumber,@RequestParam("cname") String cname){
        List<Map<String, Object>> maps = userService.selectByteaUpYear(school_year,mname,yearnumber,cname);
        return Result.success(maps);
    }
    @ApiOperation("直接查出教师下半年的课程数")
    @RequestMapping("/selectByteaDownYear")
    public Result selectByteaDownYear( @RequestParam("school_year") String school_year,@RequestParam("mname") String mname,@RequestParam("yearnumber") String yearnumber,@RequestParam("cname") String cname){
        List<Map<String, Object>> maps = userService.selectByteaDownYear(school_year,mname,yearnumber,cname);
        return Result.success(maps);
    }

    /**
     * 测试 ，到时候要调用的，前端写的是死的
     * @param nowdays
     * @return
     */
    @ApiOperation("查询今天对应的学期")
    @RequestMapping("/queryNowdays")
    public Result queryNowTerm(@RequestParam("nowdays") String nowdays){
        String nowTerm = userService.queryNowTerm(nowdays);
        return Result.success(nowTerm);
    }
    /**
     * 根据实际情况改的        测试是50         上线一定要改
     * @return
     */
    @ApiOperation("查询学生分数比较低的")
    @RequestMapping("/queryfail")
    public Result selectScore(){
        List<Map<String, Object>> queryfail = userService.queryfail();
        if(queryfail!=null && !queryfail.isEmpty()){
            return Result.success(queryfail);
        }else{
            return Result.success();
        }
    }

    @ApiOperation("查找分数占比")
    @RequestMapping("/selectproportion")
    public Result selectproportion( @RequestParam("cname") String cname){
        Map<String, Object> selectproportion = userService.selectproportion(cname);
        return Result.success(selectproportion);
    }

    @ApiOperation("课时量排名")
    @RequestMapping("/Workload_ranking")
    public Result Workload_ranking( @RequestParam("school_year") String school_year , @RequestParam("mname") String mname){
        List<Map<String, Object>> maps = userService.Workload_ranking(school_year, mname);
        return Result.success(maps);
    }

    @ApiOperation("查询前20名问题班级")
    @RequestMapping("/query_question_class")
    public Result query_question_class(){
        List<Map<String, Object>> maps = userService.query_question_class();
        return Result.success(maps);
    }
}
